package es.mgil.barriguitas;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

public final class ApnSettings {

	private static final String ID = "_id";
	private static final String APN = "apn";
	private static final String TYPE = "type";

	private static final String APN_VALUE = "internet";
	private static final String TYPE_VALUE = "default";
	private static final String USER_VALUE = "orange";

	private static final String SUFFIX = "Backup";

	private static final Uri CONTENT_URI = Uri
			.parse("content://telephony/carriers");

	private final ContentResolver contentResolver;

	public ApnSettings(ContentResolver contentResolver) {
		this.contentResolver = contentResolver;
	}

	public int getApnState() {
		int count = getNumDisabledConnections();
		return count == 0 ? ApplicationConstants.State.ON
				: ApplicationConstants.State.OFF;
	}

	private int getNumDisabledConnections() {
		Cursor cursor = null;
		try {
			cursor = contentResolver.query(CONTENT_URI,
					new String[] { "count(*)" }, "apn='" + APN_VALUE + SUFFIX
							+ "' and type='" + TYPE_VALUE + SUFFIX
							+ "' and user='" + USER_VALUE + "'", null, null);
			if (cursor.moveToFirst()) {
				return cursor.getInt(0);
			} else {
				return -1;
			}
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
	}

	public boolean switchApnState(int targetState) {
		if (targetState == ApplicationConstants.State.OFF) {
			return disableAll();
		} else {
			return enableAll();
		}
	}

	private boolean disableAll() {
		List<ApnInfo> apns = getEnabledApns();
		return disableApnList(apns);
	}

	private boolean enableAll() {
		List<ApnInfo> apns = getDisabledApns();
		return enableApnList(apns);
	}

	private List<ApnInfo> getEnabledApns() {
		String query = "apn='" + APN_VALUE + "' and type='" + TYPE_VALUE
				+ "' and user='" + USER_VALUE + "'";
		return selectApnInfo(query);
	}

	private List<ApnInfo> getDisabledApns() {
		String query = "apn='" + APN_VALUE + SUFFIX + "' and type='"
				+ TYPE_VALUE + SUFFIX + "' and user='" + USER_VALUE + "'";
		return selectApnInfo(query);
	}

	private List<ApnInfo> selectApnInfo(String whereQuery) {
		Cursor cursor = null;
		try {
			cursor = contentResolver.query(CONTENT_URI, new String[] { ID, APN,
					TYPE }, whereQuery, null, null);
			return createApnList(cursor);
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
	}

	private List<ApnInfo> createApnList(Cursor mCursor) {
		List<ApnInfo> result = new ArrayList<ApnInfo>();
		mCursor.moveToFirst();
		while (!mCursor.isAfterLast()) {
			long id = mCursor.getLong(0);
			String apn = mCursor.getString(1);
			String type = mCursor.getString(2);
			result.add(new ApnInfo(id, apn, type));
			mCursor.moveToNext();
		}
		return result;
	}

	private boolean disableApnList(List<ApnInfo> apns) {
		final ContentResolver contentResolver = this.contentResolver;
		for (ApnInfo apnInfo : apns) {
			ContentValues values = new ContentValues();
			values.put(APN, apnInfo.apn + SUFFIX);
			values.put(TYPE, apnInfo.type + SUFFIX);
			contentResolver.update(CONTENT_URI, values, ID + "=?",
					new String[] { String.valueOf(apnInfo.id) });
		}
		return true;
	}

	private boolean enableApnList(List<ApnInfo> apns) {
		final ContentResolver contentResolver = this.contentResolver;
		for (ApnInfo apnInfo : apns) {
			ContentValues values = new ContentValues();
			values.put(APN, apnInfo.apn.replace(SUFFIX, ""));
			values.put(TYPE, apnInfo.type.replace(SUFFIX, ""));
			contentResolver.update(CONTENT_URI, values, ID + "=?",
					new String[] { String.valueOf(apnInfo.id) });

		}
		return true;
	}

}

final class ApnInfo {

	final long id;
	final String apn;
	final String type;

	public ApnInfo(long id, String apn, String type) {
		this.id = id;
		this.apn = apn;
		this.type = type;
	}
}

final class ApplicationConstants {

	public static final class State {
		public static final int OFF = 0;
		public static final int ON = 1;
	}

}
